import request from '@/api/axios'
import {AxiosPromise} from 'axios'
import {DataRecordList, Paging, SeleteData, Dictionary, DataRes} from '@/api/config'
import {CallTableTextContent, getVCellMarginTop} from '@/util/pdf'
import {DocDefinition, DocContent, TableBodyData, TableLineData, TableCellStyle, TableTextContent, CallNodeData, ColumnsContent, BaseColumn} from '@/util/pdf'
import {ItemData, InforSummary, inforSummaryData, InforSummaryList} from '@/api/medicalExaminerDesk/beginPhysicalExamination/healthEvaluation'
import {DoctorList} from '@/api/medicalExaminerDesk/medicalExaminerDesk'
import {SaveInfor, HelpView} from '@/api/medicalExaminerDesk/constitutionIdentify'
import {HospitalCourse} from '@/api/medicalExaminerDesk/beginPhysicalExamination/hospitalCourse'
import {MainMedication} from '@/api/medicalExaminerDesk/beginPhysicalExamination/mainMedication'
import {VaccinationHistory} from '@/api/medicalExaminerDesk/beginPhysicalExamination/vaccinationHistory'
import {ItemList, CheckReportFileList} from '@/api/medicalExaminerDesk/beginPhysicalExamination/inspectionReport'
import {BasePhysicalExamination} from '@/api/medicalExaminerDesk/beginPhysicalExamination/index'
import {getBarcodeImgData, getYearMonthDayStr, traveTree, deepTrave, YYYYMMDDHHSSMM} from '@/util/common'

export enum PrintStatus{NOT, HAS}
export enum DistributionStatus{NOT, HAS}
//体检数据分页搜索
export interface SearchFromData{
  //总检日期
  inspectDate?:'1000-01-01 00:00:00'
  //体检日期
  phyDate?:'1000-01-01 00:00:00'
  //打印日期
  printTime?:'1000-01-01 00:00:00'
  //发放日期
  distributionTime?:'1000-01-01 00:00:00'
  //开始时间
  startTime?:string
  //结束时间
  endTime?:string
  //体检号
  checkupNo?:string
  //姓名
  personName?:string
  //性别
  gender?:string
  //社区
  teamId?:string
  //打印状态
  printStatus?:PrintStatus
  //发放状态
  distributionStatus?:DistributionStatus
  //总检医生id
  inspectDoctorId?:string
  //打印医生id
  printDoctorId?:string
  //发放医生id
  distributionDoctorId?:string
}
export interface GetReportList extends SearchFromData{
  //时间
  time:[string, string]
  //日期类型
  dateType:string
  //医生类型
  doctorType:string
  //医生Id
  doctorId?:string
}
//表格数据
export interface ReportListData{
  id:string
  //体检号
  checkupNo:string
  //姓名
  personName:string
  //身份证号
  idNo:string
  //性别
  genderName:string
  //年龄
  age:string
  //联系电话
  phone:string
  //社区
  teamName:string
  //体检日期
  phyDate:string
  //总检日期
  inspectDate:string
  //打印状态
  printStatus:PrintStatus
  //打印日期
  printTime:string
  //发放状态
  distributionStatus:DistributionStatus
  //发放日期
  distributionTime:string
}
//获取体检报告数据
export const getReportList = (params:SearchFromData&Paging):AxiosPromise<DataRecordList<ReportListData>> => {
  return request({
    url:'/api/checkupReport/page',
    method:'get',
    params
  })
}
//发放报告
export const sendReport = (data:Array<string>):AxiosPromise<DataRes<undefined>> => {
  return request({
    url:'/api/checkupReport/send',
    method:'post',
    data
  })
}

//总检医生  账号管理中“岗位”为医生的账号
export const getSumDoctorList = (): AxiosPromise<DataRes<Array<DoctorList>>> => {
  return request({
    url: '/api/user/doctor/list',
    method: 'get'
  })
}

//所有账号
export const getUserList = (): AxiosPromise<DataRes<Array<DoctorList>>> => {
  return request({
    url: '/api/user/list',
    method: 'get'
  })
}

//获取不需要打印的字段
export const getPrintKeys = (): AxiosPromise<DataRes<Array<string>|null>> => {
  return request({
    url:'/api/itemField/getField',
    method:'get'
  })
}

//打印基础信息
interface BaseReportData{
  //机构名称
  orgName:string
  //体检号
  checkupNo:string
  //姓名
  personName:string
  //性别
  gender:string
  //年龄
  age:number
  //联系电话
  phone:string
  //地址
  address:string
  //体检日期
  phyDate:string
  //打印日期
  printTime:string
  //头像
  portrait:string
  //检查医生名称
  inspectDoctorName:string
}

//不打印字段
interface NoPrintHospital{
  jtReason?:string
}
//住院情况VO
interface HospitalCourseVO extends BasePhysicalExamination{
  //住院史
  list?:Array<HospitalCourse&NoPrintHospital>
  //家庭病床史
  familyList?:Array<HospitalCourse&NoPrintHospital>
}
//用药情况VO
interface MedicationSituationVO extends BasePhysicalExamination{
  //数据
  list?:Array<MainMedication>
}

//不打印字段
interface NoPrinVacc{
  fmyUnitsName?:string
}
//非免疫规划预防接种史
interface VaccinationHistoryVO extends BasePhysicalExamination{
  //数据
  list?:Array<VaccinationHistory&NoPrinVacc>
}

interface ItemGroupList{
  //项目名称
  itemGroupName:string
  //是否打印
  isPrintBarcode:boolean
  //体检医生
  dutyDoctorName:string
  checkReportVOS:Array<ItemList>
  sort?:number|null
  createTime?:string
}
//检查报告VO
interface InspectionReportVO  extends BasePhysicalExamination{
  checkReportByItemGroupList:Array<ItemGroupList>
}
interface CheckItemGroupList{
  //项目名称
  itemGroupName:string
  //是否打印
  isPrintBarcode:boolean
  //体检医生
  dutyDoctorName:string
  //描述
  description:string
  //结果
  result:string
  //图片
  imageList?:Array<CheckReportFileList>
}
//检验报告VO
interface CheckReportVO  extends BasePhysicalExamination{
  checkReportByItemGroupList:Array<CheckItemGroupList>
}

//评估结果异常数据
interface AnomalyAndAdviceVO{
  //异常名称
  anomal:string
  //建议
  advice:string
}
//健康指导 小项
interface HealthGuideConfigVO{
  healthValue:string
}
//健康指导数据
interface HealthGuideVO{
  //标题
  bigTypeName:string
  //名称
  name:string
  //项目
  healthGuideConfigurations:Array<HealthGuideConfigVO>
}
//评估结果VO
interface HealthyAppraiseVO extends BasePhysicalExamination{
  //健康评价
  abnorSignValue:string
  //异常数据
  anomalyAndAdviceList?:Array<AnomalyAndAdviceVO>
  //异常1,2,3,4
  abnormalOne:string
  abnormalTwo:string
  abnormalThree:string
  abnormalFour:string
  //健康指导
  healthGuideList:Array<HealthGuideVO>
  //危险因素控制
  riskControlValue:string
  //指导内容
  guideValue:string
}
interface ReportData extends BaseReportData, InforSummary{
  //住院治疗情况
  hospitalCourseVO:HospitalCourseVO
  //主要用药情况
  medicationSituationVO:MedicationSituationVO
  //非免疫规划预防接种史
  vaccinationHistoryVO:VaccinationHistoryVO
  //检查报告
  inspectionReportVO:InspectionReportVO
  //检验报告
  checkReportVO:CheckReportVO
  //评估结果以及健康指导
  healthyAppraiseVO:HealthyAppraiseVO
  //中医体质
  tcmConstitutionIdentificationVO:SaveInfor
}
//获取报告数据
export const getReportData = (data:Array<string>):AxiosPromise<DataRes<Array<ReportData>>> => {
  return request({
    url:'/api/checkupReport/get/report',
    method:'post',
    data
  })
}

//根据报告数据和对照,获取列表数据
const getDataList = (config:Array<ItemData>, printKeys:Array<string>, data?:Dictionary<string|number|null>):Array<ItemData> => {
  const arr:Array<ItemData> = []
  if (!data) return arr
  //排序
  config.sort((a, b) => {
    if (a.printSort !== undefined && b.printSort !== undefined) {
      return a.printSort > b.printSort ? 1 : -1
    } else {
      return 0
    }
  })
  //特殊处理字段
  const addNameKey = {'drunkState':true, 'occupaHist':true}
  config.forEach((item) => {
    //可打印字段
    if (!printKeys.includes(item.key)) {
      const key = addNameKey[item.key] ? item.key + 'Name' : item.key
      const value = data[key]
      if (value !== undefined && value !== null) {
        arr.push({value, label:item.label, unit:item.unit, key})
      }
    }
  })
  return arr
}

/**
 * 获取表格数据
 * @param props 表头label-标题 value-prop 对应关系，先后顺序
 * @param data 数据源
 * @param merge 第一列是否合并
 * @returns 表格数据
 */
const getTableBodyData = <T>(props:Array<SeleteData>, data:Array<T>, merge?:boolean):TableBodyData => {
  const bodyData:TableBodyData = []
  //表头数据
  const headData:TableLineData = []
  props.forEach((prop) => {
    headData.push({text:prop.label, style:'table-head'})
  })
  bodyData.push(headData)
  //合并单元格相关数据
  const mergeInfo = {lastValue:'', mergeNum:0}
  data.forEach((item, i) => {
    const lineData:TableLineData = []
    props.forEach((prop, j) => {
      const value = item[prop.value + '']
      const textConent:TableTextContent = {text:value !== undefined && value !== null ? value + '' : '', style:'table-value'}
      lineData.push(textConent)
      //合并第一列
      if (merge && j === 0) {
        textConent.border = [false, false, false, true]
        if (mergeInfo.lastValue && mergeInfo.lastValue === textConent.text) {
          mergeInfo.mergeNum += 1
          textConent.text = ''
          const lastConent = bodyData[i][j] as TableTextContent
          lastConent.border = [false, false, false, false]
        } else {
          mergeInfo.lastValue = textConent.text as string
        }
      }
    })
    bodyData.push(lineData)
  })
  return bodyData
}

//设置图片数据
const setImageData = (doc:DocDefinition, data:BaseReportData) => {
  if (!doc.images) doc.images = {}
  const checkupNoData = getBarcodeImgData(data.checkupNo, 142, 45)
  if (checkupNoData) {
    doc.images['checkupNo'] = checkupNoData
  }
  if (data.portrait) {
    doc.images['portrait'] = data.portrait
  }
}

//设置封面基本信息
const setCover = (doc:DocDefinition, data:BaseReportData) => {
  const border:[boolean, boolean, boolean, boolean] = [false, false, false, false]
  const arr:Array<DocContent> = [
    {text:'健康检查报告', style:'home-title', characterSpacing:1, margin:[0, 70, 0, 0]},
    {text:'Health\texamination\treport', fontSize:18, alignment:'center', preserveLeadingSpaces:true},
    {text:'让我们共同关注您的健康', fontSize:21, alignment:'center', margin:[0, 0, 0, 37]},
    {text:data.orgName, fontSize:21, bold:true, alignment:'center', margin:[0, 0, 0, 147]},
    {
      style:'home-text',
      table:{widths:[67, 310], body:[
        [{text:'单\t\t位：', border}, {text:data.orgName}],
        [{text:'体  检  号：', border}, {text:data.checkupNo}],
        [{text:'姓\t\t名：', border}, {text:data.personName}],
        [{text:'性\t\t别：', border}, {text:data.gender}],
        [{text:'年\t\t龄：', border}, {text:`${data.age}岁`}],
        [{text:'联系电话：', border}, {text:data.phone}],
        [{text:'地\t\t址：', border}, {text:data.address}]
      ]},
      layout:{
        vLineWidth:() => 0,
        hLineWidth:(i) => {
          if (i === 0) {
            return 0
          } else {
            return 0.5
          }
        },
        paddingLeft:() => 0,
        paddingRight:() => 0,
        paddingTop:() => 9,
        paddingBottom:() => 0.1
      }
    }
  ]
  const headImage = {image:'portrait', width:88, height:120, absolutePosition:{x:390, y:512}}
  if (doc.images && doc.images[headImage.image]) {
    arr.push(headImage)
  }
  doc.content = doc.content.concat(arr)
}

//获取一般header
export const getNormalHeader = (data:BaseReportData) => {
  //30% 18% 18% 18% right
  const arr:Array<DocContent> = [
    {style:'header-text', margin:[36, 27, 36, 5], columns:[
      {width:'30%', text:'体检号：' + data.checkupNo},
      {width:'18%', text:'姓名：' + data.personName},
      {width:'18%', text:'性别：' + data.gender},
      {width:'16%', text:`年龄：${data.age}岁`},
      {text:'体检日期：' + data.phyDate, alignment:'right'}
    ]},
    {canvas:[{type:'line', x1:36, x2:559, y1:0, y2:0, lineWidth:0.5}]}
  ]
  return arr
}
//获取header
const getHeader = (currentPage: number, pageCount: number, data:BaseReportData):Array<DocContent> => {
  if (currentPage === 1) {
    return []
  } else {
    const arr = getNormalHeader(data)
    return arr
  }
}
//获取封面footer
const getCoverFooter = (currentPage: number, pageCount: number, data:BaseReportData):Array<DocContent> => {
  const arr:Array<DocContent> = [
    {text:'健康资料属于个人隐私，未经本人授权，请勿随意翻阅。', fontSize:10, alignment:'center', margin:[0, -57, 0, 7]},
    {canvas:[{type:'line', x1:22, x2:572, y1:0, y2:0, lineWidth:0.5}]},
    {columnGap:70, margin:[22, 7, 22, 0], columns:[
      {width:'45%', text:'本体检报告仅供临床参考，不作为诊断依据。', fontSize:9},
      {width:'10%', text:`${currentPage}/${pageCount}`, fontSize:10, margin:[0, 42, 0, 0], alignment:'center'},
      {width:'60%', text:data.checkupNo, alignment:'center', fontSize:10, margin:[0, 42, 0, 0]}
    ]}
  ]
  if (data.checkupNo) {
    arr.push({image:'checkupNo', width:142, height:45, absolutePosition:{x:430, y:-31}})
  }
  return arr
}
//获取一般footer
export const getNormalFooter = (currentPage: number, pageCount: number, data:BaseReportData) => {
  const arr:Array<DocContent> = [
    {canvas:[{type:'line', x1:36, x2:559, y1:0, y2:0, lineWidth:0.5}], margin:[0, 4, 0, 0]},
    {style:'footer-text', margin:[36, 5, 36, 29], columns:[
      {width:'45%', text:data.orgName},
      {width:'10%', text:`${currentPage}/${pageCount}`, alignment:'center'},
      {width:'45%', text:`打印日期：${data.printTime}`, alignment:'right'}
    ]}
  ]
  return arr
}
//获取footer
export const getFooter = (currentPage: number, pageCount: number, data:BaseReportData):Array<DocContent> => {
  if (currentPage === 1) {
    return getCoverFooter(currentPage, pageCount, data)
  } else {
    const arr = getNormalFooter(currentPage, pageCount, data)
    return arr
  }
}

//获取表头前的标题
const getTableTitle = (title?:string, doctor?:string | null):Array<DocContent> => {
  return [
    {text:title ? `【${title}】` : '标题', style:'table-title'},
    {text:doctor ? `检查医生：${doctor}` : '检查医生：', style:'table-doctor'}
  ]
}

//获取表格水平边线样式
const tableHLineStyle = (i:number):TableCellStyle|null => {
  if (i > 1) {
    return {dash:{length:2}}
  } else {
    return null
  }
}
//获取表格水平边线颜色
const tableHLineColor = (i:number):string|null => {
  if (i > 1) {
    return '#707070'
  } else {
    return null
  }
}
//获取表格单元格左内边距
const tableLeftPadding = (i:number):number|null => {
  return !i ? 5 : 0
}
const tableRightPadding = ():number|null => {
  return 0
}
//居中放置 先计算一行中最高的,然后再分别取上边距
const tablePaddingTop = (i:number, node:CallNodeData) => {
  if (i > 0) {
    const margins = getVCellMarginTop(node.table, i)
    const line = node.table.body[i]
    if (margins && line) {
      line.forEach((item, i) => {
        const cell = item as CallTableTextContent
        const marginTop = margins[i]
        if (cell._margin) {
          cell._margin[1] = marginTop
        } else {
          cell._margin = [0, marginTop, 0, 0]
        }
      })
    }
    return i ? 4 : 2
  } else {
    return i ? 4 : 2
  }
}

const setDocTable = (doc:DocDefinition, body:TableBodyData, margin:[number, number, number, number], widths:Array<string>) => {
  doc.content.push(
    {
      margin,
      table:{
        body,
        widths
      },
      layout:{
        vLineWidth:() => 0,
        hLineStyle:tableHLineStyle,
        hLineColor:tableHLineColor,
        fillColor:(i:number) => i > 0 ? null : '#D8D8D8',
        hLineWidth:(i:number) => i > 1 ? 0.5 : 0.5,
        paddingTop:tablePaddingTop,
        paddingBottom:(i:number) => i ? 4 : 2,
        paddingLeft:tableLeftPadding,
        paddingRight:tableRightPadding
      }
    }
  )
}

//分页
const setPageBreak = (doc:DocDefinition) => {
  const arr = doc.content
  const last = arr[arr.length - 1]
  if (last) last.pageBreak = 'after'
}
//排序
const sortArr = (a, b) => {
  const sortA = typeof a.sort === 'number' ? a.sort : undefined
  const sortB = typeof b.sort === 'number' ? b.sort : undefined
  const timeA = typeof a.createTime === 'string' && YYYYMMDDHHSSMM.test(a.createTime) ? new Date(a.createTime).getTime() : undefined
  const timeB = typeof b.createTime === 'string' && YYYYMMDDHHSSMM.test(b.createTime) ? new Date(b.createTime).getTime() : undefined
  const sortNum = (sortA !== undefined && sortB !== undefined) ? sortA - sortB : 0
  const timeNum = (timeA !== undefined && timeB !== undefined) ? timeA - timeB : 0
  if (sortNum) return sortNum
  else return timeNum
}
//设置基础数据
const setBaseTableData = (doc:DocDefinition, data:ReportData, item:InforSummaryList, printKeys:Array<string>, merge?:boolean) => {
  const props:Array<SeleteData> = [
    {label:'项目名称', value:'label'},
    {label:'结果', value:'value'},
    {label:'单位', value:'unit'}
  ]
  const jsonData = data[item.key]
  const dataList = getDataList([...item.data], printKeys, jsonData)
  if (dataList.length) {
    const body = getTableBodyData(props, dataList, merge)
    const title = getTableTitle(item.title + '报告单', jsonData.dutyDoctorName)
    doc.content = doc.content.concat(title),
    setDocTable(doc, body, [0, 4, 0, 16], ['34%', '48%', '18%'])
  }
}

//设置住院治疗情况
const setHospital = (doc:DocDefinition, data:HospitalCourseVO, printKeys:Array<string>, merge?:boolean) => {
  const props:Array<SeleteData> = [
    {label:'项目名称', value:'label'},
    {label:'结果', value:'value'},
    {label:'单位', value:'unit'}
  ]
  if (data) {
    const dataList:Array<ItemData> = []
    const arr:Array<HospitalCourse&NoPrintHospital> = []
    if (data.list && !printKeys.includes('reason')) {
      data.list.forEach((item) => {
        arr.push(item)
      })
    }
    if (data.familyList && !printKeys.includes('jtReason')) {
      data.familyList.forEach((item) => {
        arr.push(item)
      })
    }
    if (arr.length === 0) return
    arr.forEach((item) => {
      const label = item.styleSign ? '家庭病床史' : '住院史'
      let value = `${item.inStartDate}至${item.inEndDate}`
      if (item.reason) value += `\n住院原因：${item.reason}`
      if (item.unitsName) value += `\n医疗机构名称：${item.unitsName}`
      if (item.caseNo) value += `\n病案号：${item.caseNo}`
      dataList.push({label, value, unit:'', key:''})
    })
    const body = getTableBodyData(props, dataList, merge)
    const title = getTableTitle('住院治疗情况报告单', data.dutyDoctorName)
    doc.content = doc.content.concat(title)
    setDocTable(doc, body, [0, 4, 0, 16], ['34%', '48%', '18%'])
  }
}

//设置主要用药情况
const setUseMedication = (doc:DocDefinition, data:MedicationSituationVO, printKeys:Array<string>, merge?:boolean) => {
  if (printKeys.includes('drugName')) return
  const props:Array<SeleteData> = [
    {label:'项目名称', value:'label'},
    {label:'结果', value:'value'},
    {label:'单位', value:'unit'}
  ]
  if (data && data.list && data.list.length) {
    const dataList:Array<ItemData> = []
    data.list.forEach((item) => {
      const label = '主要用药情况'
      let value = `药物名称：${item.drugName}`
      if (item.drugUseMethodName) value += `\n用法：${item.drugUseMethodName}`
      if (item.doseName) value += `\n用量：${item.doseName}`
      if (item.drugUseTimeName) value += `\n用药时间：${item.drugUseTimeName}`
      if (item.drugCompliableName) value += `\n服药依从性：${item.drugCompliableName}`
      dataList.push({label, value, unit:'', key:''})
    })
    const body = getTableBodyData(props, dataList, merge)
    const title = getTableTitle('主要用药情况报告单', data.dutyDoctorName)
    doc.content = doc.content.concat(title)
    setDocTable(doc, body, [0, 4, 0, 16], ['34%', '48%', '18%'])
  }
}

//设置非免疫规划预防接种史
const setVaccinationHistory = (doc:DocDefinition, data:VaccinationHistoryVO, printKeys:Array<string>, merge?:boolean) => {
  //不显示非免疫历史
  if (printKeys.includes('fmyUnitsName')) return
  const props:Array<SeleteData> = [
    {label:'项目名称', value:'label'},
    {label:'结果', value:'value'},
    {label:'单位', value:'unit'}
  ]
  if (data && data.list && data.list.length) {
    const dataList:Array<ItemData> = []
    data.list.forEach((item) => {
      const label = '非免疫规划预防接种史'
      let value = `疫苗名称：${item.inocName}`
      value += `\n接种时间：${item.inocDate}`
      value += `\n接种机构：${item.unitsName}`
      dataList.push({label, value, unit:'', key:''})
    })
    if (dataList.length === 0) return
    const body = getTableBodyData(props, dataList, merge)
    const title = getTableTitle('非免疫规划预防接种史报告单', data.dutyDoctorName)
    doc.content = doc.content.concat(title)
    setDocTable(doc, body, [0, 4, 0, 16], ['34%', '48%', '18%'])
  }
}

//设置检查报告
const setInspectionReport = (doc:DocDefinition, data:InspectionReportVO, merge?:boolean) => {
  const props:Array<SeleteData> = [
    {label:'项目名称', value:'itemName'},
    {label:'结果', value:'result'},
    {label:'提示', value:'tips'},
    {label:'单位', value:'unitName'},
    {label:'参考范围', value:'viewRange'}
  ]
  if (data && data.checkReportByItemGroupList && data.checkReportByItemGroupList.length) {
    data.checkReportByItemGroupList.sort(sortArr)
    data.checkReportByItemGroupList.forEach((item) => {
      if (item.checkReportVOS.length && item.isPrintBarcode) {
        const body = getTableBodyData(props, item.checkReportVOS, merge)
        const title = getTableTitle(`${item.itemGroupName}报告单`, item.dutyDoctorName)
        doc.content = doc.content.concat(title)
        setDocTable(doc, body, [0, 4, 0, 16], ['30% ', '30%', '10%', '12%', '18%'])
      }
    })
  }
}

//设置检验报告
const setCheckReport = (doc:DocDefinition, data:CheckReportVO, index:number) => {
  if (data && data.checkReportByItemGroupList && data.checkReportByItemGroupList.length) {
    if (!doc.styles) doc.styles = {}
    doc.styles['checkreport-title'] = {fontSize:10, bold:true}
    doc.styles['checkreport-text'] = {fontSize:10}
    let sum = 0
    data.checkReportByItemGroupList.sort(sortArr)
    data.checkReportByItemGroupList.forEach((item) => {
      if (item.isPrintBarcode) {
        //如果检验报告前端有其他项目 需要另起一页
        if (index) setPageBreak(doc)
        //每个检验报告单独占一页
        if (sum) setPageBreak(doc)
        const title = getTableTitle(`${item.itemGroupName}报告单`, item.dutyDoctorName)
        doc.content = doc.content.concat(title)
        doc.content.push({canvas:[{type:'line', x1:0, x2:524, y1:0, y2:0, lineWidth:0.5}], margin:[0, 4, 0, 0]})
        doc.content.push({text:'检查描述', style:'checkreport-title', margin:[0, 7, 0, 0]})
        doc.content.push({text:item.description, style:'checkreport-text', margin:[0, 6, 0, 0]})
        doc.content.push({text:'诊断结果', style:'checkreport-title', margin:[0, 22, 0, 0]})
        doc.content.push({text:item.result, style:'checkreport-text', margin:[0, 6, 0, 0]})
        if (item.imageList && item.imageList.length) {
          const maxCol = 4
          const columns:ColumnsContent = {columnGap:11, columns:[[], [], [], []]}
          item.imageList.forEach((imageVO, i) => {
            if (imageVO.base64) {
              const index = i % maxCol
              const col = columns.columns[index] as Array<BaseColumn>
              col.push({image:imageVO.base64, width:128, height:96, margin:[0, 0, 0, 11]})
            }
          })
          doc.content.push({text:'影像附件', style:'checkreport-title', margin:[0, 6, 0, 20]})
          doc.content.push(columns)
        }
        sum++
      }
    })
  }
}

//设置评估结果以健康指导
export const setResultGuide = (doc:DocDefinition, data:HealthyAppraiseVO) => {
  if (!doc.styles) doc.styles = {}
  doc.styles['resultguide-title'] = {fontSize:13, margin:[0, -4, 0, 4], bold:true},
  doc.styles['resultguide-conent'] = {fontSize:10}
  doc.content.push({text:'【评估结果及健康指导】', style:'resultguide-title'})
  doc.content.push({canvas:[{type:'line', x1:0, x2:524, y1:0, y2:0, lineWidth:0.5}]})
  doc.content.push({text:data.abnorSignValue, style:'resultguide-conent', margin:[0, 15, 0, 0]})
  //异常数据
  if (data.anomalyAndAdviceList && data.anomalyAndAdviceList.length) {
    data.anomalyAndAdviceList.forEach((item, index) => {
      doc.content.push({text:`${index + 1}.${item.anomal}`, style:'resultguide-conent', margin:[0, 15, 0, 0]})
      if (item.advice) {
        doc.content.push({text:`【建议】${item.advice}`, style:'resultguide-conent', margin:[0, 16, 0, 0]})
      }
    })
  }
  if (data.healthGuideList && data.healthGuideList.length) {
    data.healthGuideList.forEach((healthGuide, index) => {
      doc.content.push({text:`【${healthGuide.bigTypeName}-${healthGuide.name}】`, style:'resultguide-conent', margin:[0, index ? 22 : 5, 0, 0]})
      if (healthGuide.healthGuideConfigurations) {
        healthGuide.healthGuideConfigurations.forEach((item, index) => {
          doc.content.push({text:`${index + 1}.${item.healthValue}`, style:'resultguide-conent'})
        })
      }
    })
  }
  if (data.guideValue) {
    doc.content.push({text:data.guideValue, style:'resultguide-conent', margin:[0, 15, 0, 0]})
  }
  doc.content.push({text:`检查医生：${data.dutyDoctorName}`, style:'cnmedicine-conent', margin:[0, 40, 0, 0], alignment:'right'})
}

interface TreeLv extends HelpView{
  lv?:number
  children?:Array<TreeLv>
}
//设置中医体质报告
export const setCnMedicine = (doc:DocDefinition, data:SaveInfor) => {
  if (!doc.styles) doc.styles = {}
  doc.styles['cnmedicine-title'] = {fontSize:13, margin:[0, -4, 0, 4], bold:true},
  doc.styles['cnmedicine-conent'] = {fontSize:10}
  doc.content.push({text:'【中医体质报告】', style:'cnmedicine-title'})
  doc.content.push({canvas:[{type:'line', x1:0, x2:524, y1:0, y2:0, lineWidth:0.5}]})
  doc.content.push({text:`体质类型：${data.result}`, style:'cnmedicine-conent', margin:[0, 15, 0, 15]})
  //健教指导树
  if (data.constitution) {
    const treeData:Array<TreeLv> = JSON.parse(data.constitution)
    let lvSum = 0
    const visiter = (node:TreeLv) => {
      //加上层级关系
      if (!node.lv) node.lv = 0
      if (node.children) {
        node.children.forEach((item) => {
          item.lv = node.lv !== undefined ? node.lv + 1 : 0
        })
      }
      const text = node.lv ? node.label : `【${node.label}】`
      doc.content.push({text, style:'cnmedicine-conent', margin:[0, lvSum && !node.lv ? 5 : 0, 0, 0]})
      lvSum += !node.lv ? 1 : 0
    }
    traveTree(treeData, visiter, true)
  }
  if (data.guideWriteValue) {
    doc.content.push({text:data.guideWriteValue, style:'cnmedicine-conent', margin:[0, 15, 0, 0]})
  }
  doc.content.push({text:`检查医生：${data.dutyDoctorName}`, style:'cnmedicine-conent', margin:[0, 40, 0, 0], alignment:'right'})
}

//转换数据
export const transDate = (data:ReportData, exclusion?:Array<string>) => {
  //没有打印,设置当前日期
  if (!data.printTime) {
    data.printTime = getYearMonthDayStr(Date.now())
  }
  const visiter = (value:unknown) => {
    if (typeof value === 'object' || Array.isArray(value)) {
      for (const key in value) {
        if (exclusion && exclusion.includes(key)) continue
        if (typeof value[key] === 'string' && YYYYMMDDHHSSMM.test(value[key])) {
          //只显示年月日
          value[key] = value[key].substring(0, 10)
        }
      }
    }
  }
  deepTrave(data, visiter)
}
//获取初始配置
export const getBaseDoc = ():DocDefinition => {
  const doc:DocDefinition = {
    pageSize:'A4',
    pageMargins:[36, 53, 36, 53],
    //默认宋体
    defaultStyle:{font:'SourceHanSansCN'},
    content:[],
    //配置好的样式
    styles:{
      'home-title':{fontSize:45, bold:true, alignment:'center'},
      'home-text':{fontSize:13, margin:[81, 0, 81, 0], preserveLeadingSpaces:true},
      'header-text':{fontSize:9},
      'footer-text':{fontSize:9},
      'table-head':{fontSize:10, bold:true},
      'table-value':{fontSize:10},
      'table-title':{fontSize:13, bold:true},
      'table-doctor':{fontSize:10, alignment:'right', margin:[0, -17, 0, 0]}
    }
  }
  return doc
}

//打印方法
interface ReportCallList{
  call:(index:number)=>void
  sort?:number|null
  createTime?:string
}
/**
 * 获取体检报告配置
 * @param data 数据
 * @param isPrint 是否是打印
 * @param printKeys 打印字段
 */
export const getReportDoc = (data:ReportData, isPrint:boolean, printKeys:Array<string>):Array<DocDefinition> => {
  let doc = getBaseDoc()
  const arr:Array<DocDefinition> = [doc]
  doc.header = (currentPage: number, pageCount: number) => getHeader(currentPage, pageCount, data)
  doc.footer = (currentPage: number, pageCount: number) => getFooter(currentPage, pageCount, data)
  //转换日期
  transDate(data, ['createTime'])
  //设置图片数据
  setImageData(doc, data)
  //设置封面
  setCover(doc, data)
  //打印时生成两个pdf 封面单独打印 其他双面打印
  if (isPrint) {
    doc = getBaseDoc()
    //设置图片数据
    setImageData(doc, data)
    doc.header = (currentPage: number, pageCount: number) => getHeader(currentPage + 1, pageCount + 1, data)
    doc.footer = (currentPage: number, pageCount: number) => getFooter(currentPage + 1, pageCount + 1, data)
    arr.push(doc)
  } else {
    setPageBreak(doc)
  }
  const callList:Array<ReportCallList> = []
  //设置基础项目
  inforSummaryData.forEach((item) => {
    const jsonData = data[item.key]
    if (jsonData) {
      callList.push({sort:jsonData.sort, call:() => setBaseTableData(doc, data, item, printKeys, true)})
    }
  })
  //设置住院史
  if (data.hospitalCourseVO) {
    const {sort, createTime} = data.hospitalCourseVO
    callList.push({sort, createTime, call:() => setHospital(doc, data.hospitalCourseVO, printKeys, true)})
  }
  //设置主要用药情况
  if (data.medicationSituationVO) {
    const {sort, createTime} = data.medicationSituationVO
    callList.push({sort, createTime, call:() => setUseMedication(doc, data.medicationSituationVO, printKeys, true)})
  }
  //设置非免疫规划预防接种史
  if (data.vaccinationHistoryVO) {
    const {sort, createTime} = data.vaccinationHistoryVO
    callList.push({sort, createTime, call:() => setVaccinationHistory(doc, data.vaccinationHistoryVO, printKeys, true)})
  }
  //设置检查报告
  if (data.inspectionReportVO && data.inspectionReportVO.checkReportByItemGroupList.length) {
    const {sort, createTime} = data.inspectionReportVO
    callList.push({sort, createTime, call:() => setInspectionReport(doc, data.inspectionReportVO, false)})
  }
  //设置检验报告
  if (data.checkReportVO && data.checkReportVO.checkReportByItemGroupList.length) {
    const {sort, createTime} = data.checkReportVO
    callList.push({sort, createTime, call:(i:number) => setCheckReport(doc, data.checkReportVO, i)})
  }
  //排序
  callList.sort(sortArr)
  callList.forEach((item, i) => {
    item.call(i)
  })
  if (callList.length) {
    setPageBreak(doc)
  }
  //设置评估结果及健康指导
  setResultGuide(doc, data.healthyAppraiseVO)
  setPageBreak(doc)
  //设置中医
  setCnMedicine(doc, data.tcmConstitutionIdentificationVO)
  return arr
}